#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <memory>
#include <iomanip>
#include "compiler/lexer.h"
#include "compiler/parser.h"
#include "compiler/semantic_analyzer.h"
#include "compiler/planner.h"
#include "execution/executor.h"
#include "execution/catalog.h"
#include "storage/buffer_pool.h"
#include "storage/disk_manager.h"

// Helper function: Execute SQL statements
void executeSqlStatements(const std::string& inputSql, SemanticAnalyzer& semanticAnalyzer, Executor& executor, std::shared_ptr<Catalog> catalog) {
    try {
        // 词法分析
        Lexer lexer(inputSql);
        std::vector<Token> tokens = lexer.tokenize();
        
        // 语法分析
        Parser parser(tokens);
        std::vector<std::unique_ptr<AST::Statement>> statements = parser.parseMultipleStatements();
        
        // 执行每条语句
        for (size_t i = 0; i < statements.size(); ++i) {
            const std::unique_ptr<AST::Statement>& stmt = statements[i];
            
            // 打印语句信息
            std::cout << "Executing: " << stmt->toString() << std::endl;
            
            // 语义分析
            semanticAnalyzer.analyze(stmt);
            
            // 执行计划生成
            Planner planner;
            std::unique_ptr<Execution::PlanNode> plan = planner.createPlan(stmt);
            
            // 输出执行计划信息
            std::cout << "=== Execution Plan ===" << std::endl;
            std::cout << plan->toString() << std::endl;
            
            // 输出详细四元式 (op, arg1, arg2, result)
            std::cout << "=== Detailed Quadruples ===" << std::endl;
            
            // 根据不同类型的执行计划生成四元式
            if (auto* createTablePlan = dynamic_cast<Execution::CreateTablePlan*>(plan.get())) {
                std::cout << "(CREATE_TABLE, table=" << createTablePlan->tableName << ", -, -)" << std::endl;
                for (const auto& col : createTablePlan->columns) {
                    std::cout << "(ADD_COLUMN, " << createTablePlan->tableName << ", " << col.first << ", " << col.second << ")" << std::endl;
                }
            } else if (auto* insertPlan = dynamic_cast<Execution::InsertPlan*>(plan.get())) {
                std::cout << "(INSERT_INTO, table=" << insertPlan->tableName << ", -, -)" << std::endl;
                for (size_t i = 0; i < insertPlan->values.size(); ++i) {
                    std::string colName = insertPlan->columns.empty() ? "col" + std::to_string(i+1) : insertPlan->columns[i];
                    std::cout << "(ASSIGN_VALUE, " << insertPlan->values[i] << ", -, " << colName << ")" << std::endl;
                }
                std::cout << "(EXECUTE_INSERT, table=" << insertPlan->tableName << ", -, -)" << std::endl;
            } else if (auto* selectPlan = dynamic_cast<Execution::SelectPlan*>(plan.get())) {
                std::cout << "(SCAN_TABLE, " << selectPlan->tableName << ", -, temp_row)" << std::endl;
                if (!selectPlan->filter.empty()) {
                    std::cout << "(FILTER, temp_row, condition=" << selectPlan->filter << ", filtered_row)" << std::endl;
                }
                std::cout << "(PROJECT, " << (selectPlan->filter.empty() ? "temp_row" : "filtered_row") << ", columns=";
                for (size_t i = 0; i < selectPlan->columns.size(); ++i) {
                    if (i > 0) std::cout << ",";
                    std::cout << selectPlan->columns[i];
                }
                std::cout << ", result_set)" << std::endl;
            } else if (auto* deletePlan = dynamic_cast<Execution::DeletePlan*>(plan.get())) {
                std::cout << "(SCAN_TABLE, " << deletePlan->tableName << ", -, temp_row)" << std::endl;
                if (!deletePlan->filter.empty()) {
                    std::cout << "(FILTER, temp_row, condition=" << deletePlan->filter << ", filtered_row)" << std::endl;
                }
                std::cout << "(DELETE_ROW, " << deletePlan->tableName << ", " << (deletePlan->filter.empty() ? "all_rows" : "filtered_row") << ", -)" << std::endl;
            }
            std::cout << "===================" << std::endl;
            
            // 执行
            ExecutionResult result = executor.execute(plan);
            
            // 处理执行结果
            if (!result.success) {
                std::cerr << "[EXECUTION_ERROR] " << result.message << std::endl;
                std::cerr << "Execution failed. Please check if the statement is correct or if the table exists." << std::endl;
            } else if (!result.rows.empty()) {
                // 如果有查询结果，显示表格
                
                // 获取表信息
                const AST::SelectStmt* selectStmt = dynamic_cast<const AST::SelectStmt*>(stmt.get());
                TableInfo* tableInfo = nullptr;
                std::string tableName;
                
                // 从不同类型的语句中提取表名
                if (selectStmt != NULL) {
                    tableName = selectStmt->tableName;
                } else {
                    // 尝试从执行计划中获取表名
                    if (auto* selectPlan = dynamic_cast<Execution::SelectPlan*>(plan.get())) {
                        tableName = selectPlan->tableName;
                    }
                }
                
                // 使用提取的表名查找表信息（不区分大小写）
                if (!tableName.empty()) {
                    tableInfo = catalog->getTable(tableName);
                }
                
                if (tableInfo != NULL) {
                    // 计算每列的最大宽度（包括表头和数据）
                    std::vector<size_t> maxWidths(tableInfo->columns.size(), 0);
                    
                    // 计算表头宽度
                    for (size_t j = 0; j < tableInfo->columns.size(); ++j) {
                        maxWidths[j] = tableInfo->columns[j].name.length();
                    }
                    
                    // 计算数据宽度
                    for (const auto& row : result.rows) {
                        for (size_t k = 0; k < row.size(); ++k) {
                            if (k < maxWidths.size() && row[k].length() > maxWidths[k]) {
                                maxWidths[k] = row[k].length();
                            }
                        }
                    }
                    
                    // 打印表头
                    std::cout << "| ";
                    for (size_t j = 0; j < tableInfo->columns.size(); ++j) {
                        const ColumnInfo& colInfo = tableInfo->columns[j];
                        std::cout << std::setw(maxWidths[j]) << std::left << colInfo.name << " | ";
                    }
                    std::cout << std::endl;
                    
                    // 打印分隔线
                    std::cout << "+";
                    for (size_t j = 0; j < tableInfo->columns.size(); ++j) {
                        for (size_t k = 0; k < maxWidths[j] + 2; ++k) {
                            std::cout << "-";
                        }
                        std::cout << "+";
                    }
                    std::cout << std::endl;
                    
                    // 打印数据行
                    for (const auto& row : result.rows) {
                        std::cout << "| ";
                        for (size_t k = 0; k < row.size(); ++k) {
                            if (k < maxWidths.size()) {
                                std::cout << std::setw(maxWidths[k]) << std::left << row[k] << " | ";
                            } else {
                                std::cout << row[k] << " | ";
                            }
                        }
                        std::cout << std::endl;
                    }
                    
                    // 打印表尾
                    std::cout << "+";
                    for (size_t j = 0; j < tableInfo->columns.size(); ++j) {
                        for (size_t k = 0; k < maxWidths[j] + 2; ++k) {
                            std::cout << "=";
                        }
                        std::cout << "+";
                    }
                    std::cout << std::endl;
                    
                    // 打印记录数量信息
                    std::cout << "(Total " << result.rows.size() << " records)" << std::endl;
                } else {
                    // 没有表信息时，简单显示结果
                    for (size_t j = 0; j < result.rows.size(); ++j) {
                        const std::vector<std::string>& row = result.rows[j];
                        for (size_t k = 0; k < row.size(); ++k) {
                            if (k > 0) std::cout << ", ";
                            std::cout << row[k];
                        }
                        std::cout << std::endl;
                    }
                }
            } else {
                std::cout << result.message << std::endl;
            }
        }
    } catch (const LexerError& e) {
        std::cerr << "[LEXICAL_ERROR] " << e.what() << std::endl;
        std::cerr << "Please check if the SQL statement's spelling and syntax format are correct." << std::endl;
    } catch (const ParserError& e) {
        std::cerr << "[SYNTAX_ERROR] " << e.what() << std::endl;
        std::cerr << "SQL statement structure is incorrect. Please check keyword order or missing clauses." << std::endl;
    } catch (const SemanticError& e) {
        std::cerr << "[SEMANTIC_ERROR] " << e.what() << std::endl;
        std::cerr << "Please check if table/column names exist or if data types match." << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "[SYSTEM_ERROR] " << e.what() << std::endl;
        std::cerr << "An unexpected system error occurred. Please try again or check system logs." << std::endl;
    }
}

int main(int argc, char* argv[]) {
    try {
        // 创建磁盘管理器
        std::unique_ptr<DiskManager> diskManager = std::make_unique<DiskManager>("test.db");
        
        // 创建缓冲区池
        std::unique_ptr<BufferPool> bufferPool = std::make_unique<BufferPool>(10, std::move(diskManager));
        
        // 创建目录管理器
        std::shared_ptr<Catalog> catalog = std::make_shared<Catalog>(std::move(bufferPool));
        
        // 从存储加载目录信息
        catalog->loadFromStorage();
        
        // 创建分析器和执行器
        SemanticAnalyzer semanticAnalyzer(catalog);
        Executor executor(catalog->getBufferPool(), catalog);
        
        if (argc > 1) {
            // 从文件读取SQL语句
            std::string inputSql;
            std::ifstream file(argv[1]);
            if (!file.is_open()) {
                std::cerr << "Cannot open file: " << argv[1] << std::endl;
                return 1;
            }
            std::string line;
            while (std::getline(file, line)) {
                inputSql += line + "\n";
            }
            file.close();
            
            // 执行文件中的SQL语句
            executeSqlStatements(inputSql, semanticAnalyzer, executor, catalog);
        } else {
            // 交互式模式
            std::cout << "=== SimpleDB Interactive Mode ===" << std::endl;
            std::cout << "Type SQL statements (end with semicolon) and press Enter to execute." << std::endl;
            std::cout << "Type 'quit' or 'exit' to exit interactive mode." << std::endl;
            std::cout << "======================================" << std::endl;
            
            std::string line;
            while (true) {
                std::cout << ">>> ";
                std::getline(std::cin, line);
                
                // 检查是否退出
                if (line == "quit" || line == "exit") {
                    std::cout << "Exiting SimpleDB. Goodbye!" << std::endl;
                    break;
                }
                
                // 执行SQL语句
                executeSqlStatements(line, semanticAnalyzer, executor, catalog);
            }
        }
        
        // 保存目录信息到存储
        catalog->saveToStorage();
        
        return 0;
    } catch (const LexerError& e) {
        std::cerr << "[LEXICAL_ERROR] " << e.what() << std::endl;
        std::cerr << "Please check if the SQL statement's spelling and syntax format are correct." << std::endl;
    } catch (const ParserError& e) {
        std::cerr << "[SYNTAX_ERROR] " << e.what() << std::endl;
        std::cerr << "SQL statement structure is incorrect. Please check keyword order or missing clauses." << std::endl;
    } catch (const SemanticError& e) {
        std::cerr << "[SEMANTIC_ERROR] " << e.what() << std::endl;
        std::cerr << "Please check if table/column names exist or if data types match." << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "[SYSTEM_ERROR] " << e.what() << std::endl;
        std::cerr << "An unexpected system error occurred. Please try again or check system logs." << std::endl;
    }
    
    return 1;
}
